package com.zxy.allSearcher.job.cycle;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.zxy.allSearcher.esdao.PostEsDao;
import com.zxy.allSearcher.mapper.PostMapper;
import com.zxy.allSearcher.model.dto.post.PostEsDTO;
import com.zxy.allSearcher.model.entity.Post;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 增量同步帖子到 es
 * 为啥同步数据的时间与定时时间不一致？
 * 如果时间一致，一旦同步出现的异常，这次更新的数据记录就丢失了，下一次同步也只会查询下一个时间段以内的数据
 * 同步时间范围 > 定时时间，虽然存在重复，但可以保证数据的可靠，一致性
 */
// todo 取消注释开启任务
//@Component
@Slf4j
public class IncSyncPostToEs {
    @Resource
    private PostMapper postMapper;
    @Resource
    private PostEsDao postEsDao;

    /**
     * 每分钟执行一次
     */
    @Scheduled(fixedRate = 60 * 1000)
    public void run() {
        // 查询近 5 分钟内的数据
        Date fiveMinutesAgoDate = new Date(new Date().getTime() - 5 * 60 * 1000L);
        List<Post> postList = postMapper.listPostWithDelete(fiveMinutesAgoDate);
        if (CollectionUtils.isEmpty(postList)) {
            log.info("最近5分钟内，没有增加的数据");
            return;
        }
        // 数据转换
        List<PostEsDTO> postEsDTOList = postList.stream()
                .map(PostEsDTO::objToDto)
                .collect(Collectors.toList());
        // 数据同步，db到ES
        final int pageSize = 500;  // 分批同步数据，每次同步500条，考虑性能优化最优分批值，并发
        int total = postEsDTOList.size();
        log.info("同步开始, 总记录数 {}", total);
        for (int i = 0; i < total; i += pageSize) {
            int end = Math.min(i + pageSize, total);
            log.info("同步，from {} to {}", i, end);
            postEsDao.saveAll(postEsDTOList.subList(i, end));
        }
        log.info("同步结束, 总记录数 {}", total);
    }
}
